|
|||||||||||||||||||
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover | |||||||||||||||||||
Source file | Conditionals | Statements | Methods | TOTAL | |||||||||||||||
Manager.java | 72.2% | 88.5% | 100% | 86.8% |
|
1 |
/*
|
|
2 |
* $Id: Manager.java,v 1.1 2004/12/15 14:18:08 patforna Exp $
|
|
3 |
*
|
|
4 |
* Copyright (c) 2004 Patric Fornasier, Pawel Kowalski
|
|
5 |
* Berne University of Applied Sciences
|
|
6 |
* School of Engineering and Information Technology
|
|
7 |
* All rights reserved.
|
|
8 |
*/
|
|
9 |
package bexee.admin;
|
|
10 |
|
|
11 |
import java.io.ByteArrayInputStream;
|
|
12 |
import java.io.InputStream;
|
|
13 |
import java.util.ArrayList;
|
|
14 |
import java.util.Collection;
|
|
15 |
import java.util.Hashtable;
|
|
16 |
import java.util.Iterator;
|
|
17 |
import java.util.List;
|
|
18 |
import java.util.Map;
|
|
19 |
|
|
20 |
import javax.wsdl.Definition;
|
|
21 |
import javax.wsdl.Input;
|
|
22 |
import javax.wsdl.Operation;
|
|
23 |
import javax.wsdl.Output;
|
|
24 |
import javax.wsdl.Part;
|
|
25 |
import javax.wsdl.PortType;
|
|
26 |
import javax.wsdl.extensions.ExtensionRegistry;
|
|
27 |
import javax.wsdl.factory.WSDLFactory;
|
|
28 |
import javax.wsdl.xml.WSDLReader;
|
|
29 |
import javax.xml.namespace.QName;
|
|
30 |
|
|
31 |
import org.apache.axis.AxisEngine;
|
|
32 |
import org.apache.axis.AxisFault;
|
|
33 |
import org.apache.axis.ConfigurationException;
|
|
34 |
import org.apache.axis.EngineConfiguration;
|
|
35 |
import org.apache.axis.MessageContext;
|
|
36 |
import org.apache.axis.configuration.FileProvider;
|
|
37 |
import org.apache.axis.deployment.wsdd.WSDDConstants;
|
|
38 |
import org.apache.axis.deployment.wsdd.WSDDDeployment;
|
|
39 |
import org.apache.axis.deployment.wsdd.WSDDException;
|
|
40 |
import org.apache.axis.deployment.wsdd.WSDDOperation;
|
|
41 |
import org.apache.axis.deployment.wsdd.WSDDService;
|
|
42 |
import org.apache.axis.deployment.wsdd.WSDDUndeployment;
|
|
43 |
import org.apache.axis.description.OperationDesc;
|
|
44 |
import org.apache.axis.description.ParameterDesc;
|
|
45 |
import org.apache.axis.description.ServiceDesc;
|
|
46 |
import org.apache.axis.handlers.soap.SOAPService;
|
|
47 |
import org.apache.axis.utils.XMLUtils;
|
|
48 |
import org.apache.commons.logging.Log;
|
|
49 |
import org.apache.commons.logging.LogFactory;
|
|
50 |
import org.w3c.dom.Document;
|
|
51 |
|
|
52 |
import bexee.dao.BPELProcessDAO;
|
|
53 |
import bexee.dao.DAOException;
|
|
54 |
import bexee.dao.DAOFactory;
|
|
55 |
import bexee.model.BPELDocumentException;
|
|
56 |
import bexee.model.BPELProcessFactory;
|
|
57 |
import bexee.model.process.BPELProcess;
|
|
58 |
import bexee.wsdl.extensions.partnerlinktype.PartnerLinkTypeExtensionRegistry;
|
|
59 |
|
|
60 |
/**
|
|
61 |
* The <code>Manager</code> is used in bexee for deployment of BPEL business
|
|
62 |
* processes and the related WSLD descriptions.
|
|
63 |
*
|
|
64 |
* @version $Revision: 1.1 $, $Date: 2004/12/15 14:18:08 $
|
|
65 |
* @author Patric Fornasier
|
|
66 |
* @author Pawel Kowalski
|
|
67 |
*/
|
|
68 |
public class Manager { |
|
69 |
|
|
70 |
private static Log log = LogFactory.getLog(Manager.class); |
|
71 |
|
|
72 |
/**
|
|
73 |
* Deploys a BPEL process to the bexee engine and registers it in Axis as a
|
|
74 |
* web service. This method performs the following operations in the given
|
|
75 |
* order:
|
|
76 |
* <p>
|
|
77 |
* <ol>
|
|
78 |
* <li>Checks the WSDL and BPEL namespaces</li>
|
|
79 |
* <li>Create a new <code>BPELProcess</code> with a
|
|
80 |
* <code>BPELProcessFactory</code></li>
|
|
81 |
* <li>Deploys a new web service to Axis under the name defined in the BPEL
|
|
82 |
* document</li>
|
|
83 |
* <li>Returns a <code>SOAPBodyElement</code> of the form
|
|
84 |
* <manager>result text</manager>
|
|
85 |
* </ol>
|
|
86 |
*
|
|
87 |
* @param input
|
|
88 |
* <code>elems[0]</code> must be an <code>Element</code>
|
|
89 |
* representing a BPEL document , while <code>elems[1]</code>
|
|
90 |
* must be an <code>Element</code> represent a BPEL document.
|
|
91 |
* elems[1..n] can be further additional WSDL documents.
|
|
92 |
*
|
|
93 |
* @return an <code>Element[]</code>, whose first element contains a
|
|
94 |
* message that the service was deployed.
|
|
95 |
*/
|
|
96 | 4 |
public String deploy(String[] input) throws DeploymentException { |
97 |
|
|
98 | 4 |
if (input == null || input.length < 2) { |
99 | 0 |
throw new DeploymentException("at least two elems expected"); |
100 |
} |
|
101 |
|
|
102 |
// declare some variables
|
|
103 | 4 |
BPELProcess bpel = null;
|
104 | 4 |
Definition wsdl = null;
|
105 | 4 |
List partnerWSDL = new ArrayList();
|
106 |
|
|
107 |
// get reference to Axis engine and its deployment data
|
|
108 | 4 |
AxisEngine axis = getAxisEngine(); |
109 | 4 |
WSDDDeployment deployment = getDeployment(); |
110 |
|
|
111 | 4 |
try {
|
112 |
// try to create a new BPELProcess from the input we've got
|
|
113 | 4 |
bpel = createBPELProcess(input[0]); |
114 |
} catch (BPELDocumentException e) {
|
|
115 | 0 |
throw new DeploymentException("Unable to create BPELProcess", e); |
116 |
} |
|
117 |
|
|
118 | 4 |
try {
|
119 |
// create WSDL Definition object using WSDL4J
|
|
120 | 4 |
WSDLReader wsdlReader = WSDLFactory.newInstance().newWSDLReader(); |
121 |
|
|
122 |
// register extension partner links
|
|
123 | 4 |
ExtensionRegistry reg = new PartnerLinkTypeExtensionRegistry();
|
124 | 4 |
wsdlReader.setExtensionRegistry(reg); |
125 | 4 |
wsdlReader.setFeature("javax.wsdl.importDocuments", true); |
126 |
|
|
127 |
// create Definition for process WSDL
|
|
128 | 4 |
InputStream is = new ByteArrayInputStream(input[1].getBytes());
|
129 | 4 |
Document doc = XMLUtils.newDocument(is); |
130 | 4 |
wsdl = wsdlReader.readWSDL(null, doc);
|
131 |
|
|
132 |
// create Definition for additional WSDL
|
|
133 | 4 |
for (int i = 2; i < input.length; i++) { |
134 | 2 |
is = new ByteArrayInputStream(input[i].getBytes());
|
135 | 2 |
doc = XMLUtils.newDocument(is); |
136 | 2 |
Definition definition = wsdlReader.readWSDL(null, doc);
|
137 | 2 |
partnerWSDL.add(definition); |
138 |
} |
|
139 |
} catch (Exception e) {
|
|
140 | 0 |
throw new DeploymentException("Unable to create Definition", e); |
141 |
} |
|
142 |
|
|
143 |
// create a new Axis service for each port type defined in the WSDL
|
|
144 | 4 |
Collection portTypes = wsdl.getPortTypes().values(); |
145 | 4 |
String targetNS = wsdl.getTargetNamespace(); |
146 | 4 |
for (Iterator portIter = portTypes.iterator(); portIter.hasNext();) {
|
147 | 4 |
PortType portType = (PortType) portIter.next(); |
148 |
|
|
149 |
// create the new WSDD service
|
|
150 | 4 |
WSDDService service = new WSDDService();
|
151 | 4 |
ServiceDesc serviceDesc = service.getServiceDesc(); |
152 |
|
|
153 |
// set names
|
|
154 |
// service.setQName(portType.getQName());
|
|
155 |
// service.setName(portType.getQName().getLocalPart());
|
|
156 |
// serviceDesc.setName(portType.getQName().getLocalPart());
|
|
157 |
|
|
158 |
// FIXME right now only one port type is supported!!!
|
|
159 | 4 |
String name = bpel.getName(); |
160 | 4 |
service.setQName(new QName(name));
|
161 | 4 |
service.setName(name); |
162 | 4 |
serviceDesc.setName(name); |
163 |
|
|
164 |
// our own provider should handle this service -> java:BexeeProvider
|
|
165 | 4 |
service.setProviderQName(new QName(WSDDConstants.URI_WSDD_JAVA,
|
166 |
"BexeeProvider"));
|
|
167 |
|
|
168 |
// set namespace mappings
|
|
169 | 4 |
Map nsMap = wsdl.getNamespaces(); |
170 | 4 |
serviceDesc.setNamespaceMappings(new ArrayList(nsMap.entrySet()));
|
171 |
|
|
172 |
// add operations to service description
|
|
173 | 4 |
List operations = portType.getOperations(); |
174 | 4 |
for (Iterator oIter = operations.iterator(); oIter.hasNext();) {
|
175 | 4 |
Operation operation = (Operation) oIter.next(); |
176 |
|
|
177 | 4 |
OperationDesc operationDesc = new OperationDesc();
|
178 | 4 |
operationDesc.setName(operation.getName()); |
179 |
|
|
180 |
// add input parameters (parts) to operation description
|
|
181 | 4 |
Input in = operation.getInput(); |
182 | 4 |
Collection inParts = in.getMessage().getParts().values(); |
183 | 4 |
for (Iterator partIter = inParts.iterator(); partIter.hasNext();) {
|
184 | 4 |
Part part = (Part) partIter.next(); |
185 | 4 |
ParameterDesc paramDesc = new ParameterDesc();
|
186 | 4 |
paramDesc.setName(part.getName()); |
187 |
|
|
188 | 4 |
paramDesc.setQName(new QName(targetNS, part.getName()));
|
189 |
|
|
190 | 4 |
paramDesc.setTypeQName(part.getTypeName()); |
191 | 4 |
paramDesc.setMode(ParameterDesc.IN); |
192 |
|
|
193 | 4 |
operationDesc.addParameter(paramDesc); |
194 |
} |
|
195 |
|
|
196 |
// make sure that there's only one part in the output message
|
|
197 | 4 |
Output out = operation.getOutput(); |
198 | 4 |
Collection outParts = out.getMessage().getParts().values(); |
199 | 4 |
if (outParts.size() == 0) {
|
200 | 0 |
throw new DeploymentException( |
201 |
"No message part defined for output in operation "
|
|
202 |
+ operation.getName()); |
|
203 |
} |
|
204 | 4 |
if (outParts.size() > 1) {
|
205 | 0 |
throw new DeploymentException( |
206 |
"More than one message part defined for output in operation "
|
|
207 |
+ operation.getName()); |
|
208 |
} |
|
209 |
|
|
210 |
/*
|
|
211 |
* set operation return information note that it is not possible
|
|
212 |
* to use our own namespace prefixes. The only way to do this is
|
|
213 |
* upon rendering the wsdd by calling the SerializationContext
|
|
214 |
* registerPrefixForURI() method
|
|
215 |
*/
|
|
216 | 4 |
Part part = (Part) outParts.iterator().next(); |
217 | 4 |
operationDesc |
218 |
.setReturnQName(new QName(targetNS, part.getName()));
|
|
219 | 4 |
operationDesc.setReturnType(part.getTypeName()); |
220 |
|
|
221 | 4 |
service.addOperation(new WSDDOperation(operationDesc));
|
222 |
} |
|
223 |
|
|
224 |
/*
|
|
225 |
* The parameters variable in the Axis class
|
|
226 |
* org.apache.axis.deployment.wsdd.DeployableItem doesn't get
|
|
227 |
* initialized when using the no-arg constructor. This results in a
|
|
228 |
* NullPointerException when calling service.validateDescriptors().
|
|
229 |
* Thus we have to somehow initialize this variable which can be
|
|
230 |
* achieved by calling the method on the next line. Hopefully this
|
|
231 |
* will be fixed in a future release of Axis.
|
|
232 |
*/
|
|
233 | 4 |
service.setOptionsHashtable(new Hashtable());
|
234 |
|
|
235 | 4 |
try {
|
236 |
// validate descriptor before deploying service
|
|
237 | 4 |
service.validateDescriptors(); |
238 |
} catch (WSDDException e) {
|
|
239 | 0 |
throw new DeploymentException("Invalid WSDD", e); |
240 |
} |
|
241 |
|
|
242 |
// add replace the service to the deployment configuration
|
|
243 |
// existing services with the same name will be replaced
|
|
244 | 4 |
deployment.deployService(service); |
245 |
} |
|
246 |
|
|
247 | 4 |
try {
|
248 |
// notify the engine of the changes (this will also save the wsdd)
|
|
249 | 4 |
axis.refreshGlobalOptions(); |
250 |
} catch (ConfigurationException e) {
|
|
251 | 0 |
throw new DeploymentException("Unable to refresh Axis config", e); |
252 |
} |
|
253 |
|
|
254 |
// add WSDL file describing BPEL process to BPELprocess
|
|
255 | 4 |
bpel.setWSDL(wsdl); |
256 |
|
|
257 |
// add partner WSDL files
|
|
258 | 4 |
bpel.addPartnerWSDL(partnerWSDL); |
259 |
|
|
260 |
// stroe BPEL process
|
|
261 | 4 |
DAOFactory factory = DAOFactory.getInstance(); |
262 | 4 |
BPELProcessDAO dao = factory.createBPELProcessDAO(); |
263 | 4 |
String id; |
264 | 4 |
try {
|
265 | 4 |
id = dao.replace(bpel); |
266 |
} catch (DAOException e) {
|
|
267 | 0 |
throw new DeploymentException("Unable to insert/update process", e); |
268 |
} |
|
269 |
|
|
270 | 4 |
return "BPEL process succesfully updated, id: " + id; |
271 |
} |
|
272 |
|
|
273 | 2 |
public String undeploy(String name) throws DeploymentException { |
274 |
|
|
275 | 2 |
String result = null;
|
276 |
|
|
277 | 2 |
AxisEngine axis = getAxisEngine(); |
278 | 2 |
WSDDDeployment deployment = getDeployment(); |
279 |
|
|
280 | 2 |
SOAPService service; |
281 | 2 |
try {
|
282 | 2 |
service = axis.getService("TravelProcess");
|
283 |
} catch (AxisFault e) {
|
|
284 | 0 |
throw new DeploymentException("Unable to get service"); |
285 |
} |
|
286 |
|
|
287 |
// we don't want to throw an exception here
|
|
288 | 2 |
if (service == null) { |
289 | 0 |
return "No such service found to undeploy, name: " + name; |
290 |
} |
|
291 |
|
|
292 |
// create undeployment descriptor
|
|
293 | 2 |
WSDDUndeployment undeployment = new WSDDUndeployment();
|
294 | 2 |
undeployment.addService(new QName("", name)); |
295 |
|
|
296 | 2 |
try {
|
297 |
// undeploy from Axis
|
|
298 | 2 |
undeployment.undeployFromRegistry(deployment); |
299 | 2 |
axis.refreshGlobalOptions(); |
300 |
} catch (ConfigurationException e) {
|
|
301 | 0 |
throw new DeploymentException("Unable to undeploy service '" + name |
302 |
+ "' from Axis");
|
|
303 |
} |
|
304 | 2 |
try {
|
305 |
// TODO: Do we really want to delete the process and context data?
|
|
306 |
// undeploy from bexee
|
|
307 | 2 |
DAOFactory factory = DAOFactory.getInstance(); |
308 | 2 |
BPELProcessDAO dao = factory.createBPELProcessDAO(); |
309 | 2 |
dao.delete(name); |
310 |
// TODO: delete ProcessContext instances
|
|
311 |
} catch (DAOException e) {
|
|
312 | 0 |
throw new DeploymentException("Unable to undeploy from bexee", e); |
313 |
} |
|
314 |
|
|
315 | 2 |
return "Service succesfully undeployed, name: " + name; |
316 |
} |
|
317 |
|
|
318 |
/**
|
|
319 |
* Get the WSDD Deployment from the Axis engine
|
|
320 |
*/
|
|
321 | 6 |
private WSDDDeployment getDeployment() throws DeploymentException { |
322 |
|
|
323 | 6 |
WSDDDeployment deployment = null;
|
324 |
|
|
325 | 6 |
AxisEngine axis = getAxisEngine(); |
326 |
|
|
327 |
// get the engine configuration
|
|
328 | 6 |
EngineConfiguration config = axis.getConfig(); |
329 |
|
|
330 |
/*
|
|
331 |
* We are using a wsdd file to store configuration data. Unfortunately
|
|
332 |
* Axis doesn't provide all the functionality we need in the
|
|
333 |
* EngineConfiguration interface, so we have to make a downcast here :(
|
|
334 |
*/
|
|
335 | 6 |
if (config instanceof FileProvider) { |
336 | 6 |
deployment = ((FileProvider) config).getDeployment(); |
337 |
} else {
|
|
338 | 0 |
throw new DeploymentException("WSDDDeployment supported only!"); |
339 |
} |
|
340 | 6 |
return deployment;
|
341 |
} |
|
342 |
|
|
343 |
/**
|
|
344 |
* Get the Axis Engine
|
|
345 |
*/
|
|
346 | 12 |
private AxisEngine getAxisEngine() {
|
347 |
// get message context to gain access to Axis engine
|
|
348 | 12 |
MessageContext ctx = MessageContext.getCurrentContext(); |
349 | 12 |
AxisEngine axis = ctx.getAxisEngine(); |
350 | 12 |
return axis;
|
351 |
} |
|
352 |
|
|
353 |
/**
|
|
354 |
* Create a new <code>BPELProcess</code> given a bpel xml document.
|
|
355 |
*
|
|
356 |
* @param bpel
|
|
357 |
* the bpel document tree
|
|
358 |
* @return a <code>BPELProcess</code>
|
|
359 |
* @throws BPELDocumentException
|
|
360 |
*/
|
|
361 | 4 |
protected BPELProcess createBPELProcess(String bpel)
|
362 |
throws BPELDocumentException {
|
|
363 |
// convert bpel process to stream and let factory create a BPELProcess
|
|
364 | 4 |
byte[] bytes = bpel.getBytes();
|
365 | 4 |
InputStream is = new ByteArrayInputStream(bytes);
|
366 | 4 |
return BPELProcessFactory.getInstance().createBPELProcess(is);
|
367 |
} |
|
368 |
} |
|